package cn.wgx.modules.sys.services;

import cn.wgx.commons.util.StringUtils;
import cn.wgx.commons.util.Validation;
import cn.wgx.modules.base.services.BaseService;
import cn.wgx.modules.sys.entity.SysDict;
import cn.wgx.modules.sys.entity.SysDictExample;
import cn.wgx.modules.sys.entity.mapper.SysDictMapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class SysDictService extends BaseService<SysDict> {

    public  static final  String cacheName = "dictCache" ;
    
    @Resource
    SysDictMapper mapper;


    @Transactional(readOnly = true)
//    @Cacheable(value = cacheName, unless="#result == null", key = "#root.target.getCachePreKey() + #sysDict.hashCode()")
    public List<SysDict> getList(SysDict sysDict, String title, String order) {
        return getList(sysDict, title, order, null);
    }


    @Transactional(readOnly = true)
//    @Cacheable(value = cacheName, unless="#result == null", key = "#root.target.getCachePreKey() + #sysDict.hashCode() + #extendSql")
    public List<SysDict> getList(SysDict sysDict, String title, String order, String extendSql) {
        SysDictExample example = new SysDictExample();
        SysDictExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysDict.getType())) {
            criteria.andTypeEqualTo(sysDict.getType());
        }
        if (StringUtils.isNotBlank(sysDict.getK())) {
            criteria.andKEqualTo(sysDict.getK());
        }
        if(StringUtils.isNotBlank(sysDict.getRemarks())){
            criteria.andRemarksEqualTo(sysDict.getRemarks());
        }
        if (null != sysDict.getDict_id()) {
            criteria.andDict_idEqualTo(sysDict.getDict_id());
        }
        if (StringUtils.isNotBlank(sysDict.getV())) {
            if("-1".equals(title)){
                //  -1时,需要精确查询
                criteria.andVEqualTo(sysDict.getV());
            }else{
                criteria.andVLike("%" + sysDict.getV() + "%");
            }
        }
        if (StringUtils.isNotBlank(sysDict.getParentKey())) {
            criteria.andParentKeyEqualTo(sysDict.getParentKey());
        }
        if (sysDict.getParentId() != null) {
            criteria.andParentIdEqualTo(sysDict.getParentId());
        }
        if(StringUtils.isNotBlank(extendSql)){
            addCustomSQL(criteria, extendSql);
        }
        if(null == title){
            title = "sort";
        }
        if(!"-1".equals(title)){ // title为-1时,不需要排序
            if ("desc".equals(order)) {
                example.setOrderByClause(title + " desc");
            } else if (null != order) {
                example.setOrderByClause(title + " asc");
            }
        }
        return mapper.selectByExample(example);
    }

    @Transactional(readOnly = true)
    public List<SysDict> getListByIds(List<Integer> ids) {
        if(ids == null || ids.isEmpty()){
            return emptyList;
        }
        List<Integer> uniList = getUniList(ids);
        if(!uniList.isEmpty()){
            SysDictExample example = new SysDictExample();
            SysDictExample.Criteria criteria = example.createCriteria();
            criteria.andDict_idIn(uniList);
            List<SysDict> eduCourseAssignmentHis = mapper.selectByExample(example);
            return eduCourseAssignmentHis;
        }
        return null;
    }


    @Transactional(readOnly = true)
//    @Cacheable(value = cacheName, unless="#result == null", key = "#root.target.getCachePreKey() + ALL_TYPE")
    public Set<String> getTypeSet() {
        List<String> m = mapper.getTypeSet();
        Set<String> set = new HashSet<>();
        set.addAll(m);
        return set;
    }

    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int insertOne(SysDict record) {
        filter(record, true);
        record.set_result(mapper.insertSelective(record));
        return record.get_result();
    }


    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public List<SysDict> insertList(List<SysDict> records) {
        filter(records, true);
        int n = 0;
        for(SysDict sysDict: records){
            n += insertOne(sysDict);
        }
        return records;
    }



    @CacheEvict(value = cacheName, allEntries = true)
    @Transactional
    public int updateOne(SysDict record) {
        filter(record, false);
        int n = mapper.updateByPrimaryKeySelective(record);
        return n;
    }

    @CacheEvict(value = cacheName, allEntries = true)
    @Transactional
    public int updateByIDAndType(SysDict record) {
        if(Validation.isNullOrZero(record.getDict_id()) || StringUtils.isBlank(record.getType())){
            return -1;
        }
        filter(record, false);
        SysDictExample example = new SysDictExample();
        SysDictExample.Criteria criteria = example.createCriteria();
        criteria.andDict_idEqualTo(record.getDict_id()).andTypeEqualTo(record.getType());
        int n = mapper.updateByExampleSelective(record, example);
        return n;
    }

    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int updateByTypeAndKey(String type, String key, String v) {
        if(StringUtils.isBlank(type) || StringUtils.isBlank(key)){
            return -1;
        }
        SysDict record = new SysDict();
        record.setV(v);
        filter(record, false);
        SysDictExample example = new SysDictExample();
        SysDictExample.Criteria criteria = example.createCriteria();
        criteria.andTypeEqualTo(type).andKEqualTo(key);
        int n = mapper.updateByExampleSelective(record, example);
        return n;
    }

    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int deleteOne(Integer id) {
        int n = mapper.deleteByPrimaryKey(id);
        return n;
    }


    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int deleteByType(String type) {
        SysDictExample example = new SysDictExample();
        example.createCriteria().andTypeEqualTo(type);
        int n = 0;
        n = mapper.deleteByExample(example);
        return n;
    }

    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int deleteByTypeAndId(String type, Integer id) {
        SysDictExample example = new SysDictExample();
        example.createCriteria().andTypeEqualTo(type).andDict_idEqualTo(id);
        int n = 0;
        n = mapper.deleteByExample(example);
        return n;
    }

    /**
     * 手动清除缓存
     * @return
     */
    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int clearCache() {
        return clearCache(null);
    }

    /**
     * 手动清除指定缓存
     * @return
     */
    @Transactional
    @CacheEvict(value = cacheName, allEntries = true)
    public int clearCache(String type) {
        return 1;
    }


    private void filter(List<SysDict> sysDicts, boolean insert) {
        for(SysDict sysDict: sysDicts){
            filter(sysDict, insert);
        }
    }


    /**
     * 检测部门/团队名是否占用,true可创建
     *
     * @param v
     * @return
     */
    public boolean checkV(String v) {
        SysDictExample example = new SysDictExample();
        SysDictExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(v)) {
            criteria.andVLike(v);
        }
        if (mapper.selectByExample(example).isEmpty()) {
            return true;
        }
        return false;
    }
}